<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MyPromise</title>
    <script src="MyPromise.js"></script>
    <script src="debug.js"></script>
</head>
<body>
    <script>
    // then
    // var p1 = new MyPromise(function(resolve, reject) {
    //     resolve(1);
    // })
    // var p2 = p1.then(function(future) {console.log(future); return future + 1;}, onRejected)
    // var p3 = p2.then(onFulfilled)
    // p3.then(onFulfilled, onRejected);
    // console.log(p1 === p2);
    // console.log(p2 === p3);
    // console.log(p1 === p3);
        // 2个console都应该输出
        // resolve/reject不会中断执行流
        // new MyPromise(function(resolve, reject) {
        //     resolve(1);
        //     console.log('122');
        //     reject('x');
        //     console.log('2333');
        // })
        // .then(onFulfilled, function(error) {console.log('log onRejected: ' + error); return 'cuwoubeichidiaole'})
        // .then(onFulfilled)
        // // catch会阻断then 结果和错误 传递
        // .catch(onRejected)
        // .then(onFulfilled, onRejected);
    // new MyPromise(function(resolve, reject) {
    //     // resolve(1);
    //     reject(new Error('reject with no reason'));
    // }).then(function(future) {
    //     console.log('received future: ' + future);
    //     return 111;
    // }, function(error) {
    //     console.log('received error: ' + error);
    //     return 222;
    // }).then(function(future) {
    //     console.log('received future2: ' + future);
    // }, function(error) {
    //     console.log('received error2: ' + error);
    // })
    
    // catch
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).catch(onRejected);
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(null, onRejected);
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(undefined, onRejected);
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(false, onRejected);
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(true, onRejected);
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(111, onRejected).then(onFulfilled, onRejected);
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(true, onRejected).then(true).then(alert)
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(true).then(true).then(alert)
    // new MyPromise(function(resolve, reject) {
    //     resolve(111);
    // }).then(true).then(true).then(alert)
    // new MyPromise(function(resolve, reject) {
    //     reject(new Error('xxx'));
    // }).then(true, 222).then(true).then(alert)
    
    // resolve
    // MyPromise.resolve({
    //     then: function(onFulfilled, onRejected) {
    //         onFulfilled(1);
    //         onRejected(new Error('obj.then err'));

    //         console.log('obj.then');
    //     }
    // }).then(onFulfilled, function() {
    //     return 222;
    // }).then(onFulfilled, onRejected);
    // MyPromise.resolve(1).then(onFulfilled, onRejected);
    

    // reject
    // MyPromise.reject(new Error('static reject')).then(onFulfilled, onRejected);
    // MyPromise.reject(500).then(onFulfilled, onRejected);
    // MyPromise.reject(getMyPromise()).then(onFulfilled, onRejected);
    // MyPromise.reject({
    //     then: function(onFulfilled, onRejected) {
    //         console.log('obj.then');
    //     }
    // }).then(onFulfilled, onRejected).then(onFulfilled, onRejected);
    

    // all
    // MyPromise.all([111, true, new MyPromise(function(resolve, reject) {resolve(3);}), getMyPromise(), getMyPromise()]).then(onFulfilled, onRejected);
    // MyPromise.all([getMyPromise(), getMyPromise()]).then(onFulfilled, onRejected);
    // MyPromise.all([getMyPromise(), MyPromise.all([getMyPromise()])])
    // .then(function(future) {console.log(future); return 222;}, onRejected)
    // .then(onFulfilled, onRejected)
    // .then(onFulfilled, onRejected);
    // MyPromise.all([getMyPromise(true), getMyPromise(true)]).then(onFulfilled, onRejected);
    // MyPromise.all([getMyPromise(true), getMyPromise()]).then(onFulfilled, onRejected);
    // MyPromise.all([getMyPromise(), 11, getMyPromise(true), 22, getMyPromise(true)]).then(onFulfilled, onRejected);
    // MyPromise.all([getMyPromise(), 11, getMyPromise(), 22, getMyPromise(true)]).then(onFulfilled, onRejected);
    

    // race
    // MyPromise.race([111, getMyPromise(), getMyPromise()]).then(onFulfilled, onRejected);
    // MyPromise.race([getMyPromise(), getMyPromise(), 111]).then(onFulfilled, onRejected);
    // MyPromise.race([getMyPromise(), getMyPromise()]).then(onFulfilled, onRejected);
    // MyPromise.race([getMyPromise(true), getMyPromise(true)]).then(onFulfilled, onRejected);
    // MyPromise.race([getMyPromise(true), getMyPromise()]).then(onFulfilled, onRejected);
    // MyPromise.race([getMyPromise(true), getMyPromise(), 111]).then(onFulfilled, onRejected);
    // MyPromise.race([getMyPromise(), 111, getMyPromise(true)]).then(onFulfilled, onRejected);


    // 外层then能够拿到内层future和error
    // new Promise(function(resolve, reject) {
    //     resolve(new Promise(function(resolve, reject) {
    //         resolve(12);
    //         reject(new Error('reject in nested Promise'));
    //     }).then(function(future) {
    //         return future + 1;
    //     }, function(error) {
    //         return new Error('reject again in nested Promise');
    //     }));
    // }).then(onFulfilled, onRejected);
    


    // 高级功能：结果自动外抛
    // new MyPromise(function(resolve, reject) {
    //     resolve(new MyPromise(function(resolve, reject) {
    //         resolve(12);
    //         reject(new Error('reject in nested Promise'));
    //     }).then(function(future) {
    //         return future + 1;
    //     }, function(error) {
    //         console.log(error);
    //         return new Error('reject again in nested Promise');
    //     }));
    // }).then(function(future) {console.log(future); return 123;}, onRejected)
    // .then(onFulfilled, onRejected).then(onFulfilled, onRejected);
    // 等价于
    new MyPromise(function(resolve, reject) {
        var p = new MyPromise(function(resolve, reject) {
            resolve(12);
            reject(new Error('reject in nested Promise'));
        }).then(function(future) {
            return future + 1;
        }, function(error) {
            console.log(error);
            return new Error('reject again in nested Promise');
        });

        resolve(p);
    }).then(function(future) {console.log(future); return 123;}, onRejected)
    .then(onFulfilled, onRejected).then(onFulfilled, onRejected);

    // new MyPromise(function(resolve, reject) {
    //     resolve(new MyPromise(function(resolve, reject) {
    //         resolve(12);
    //         reject(new Error('reject in nested Promise'));
    //     }).then(function(future) {
    //         return future + 1;
    //     }, function(error) {
    //         return new Error('reject again in nested Promise');
    //     }).then(function(future) {
    //         return future + 2;
    //     }, function(error) {
    //         return new Error('reject again again in nested Promise');
    //     }));
    // }).then(onFulfilled, onRejected).then(onFulfilled, onRejected);
    







    // chrome立即报错，FF不报错，其它polyfill不报错
    // var p = new Promise(function(resolve, reject) {
    //     reject(new Error('x'));
    // });
    // setTimeout(function() {
    //     p.then(null, function(error) {
    //         console.log('eat x');
    //     });
    // }, 3000);
    // var p = new MyPromise(function(resolve, reject) {
    //     reject(new Error('x'));
    // });
    // setTimeout(function() {
    //     p.then(null, function(error) {
    //         console.log('eat x');
    //     });
    // }, 3000);
    // 一旦throw就无法改变message
    // var err = new Error('111');
    // throw err;
    // err.message = '222';
    </script>
</body>
</html>